package com.coffeeloversupportlibrary.core.base;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModel;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.lifecycle.ViewModelProvider;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @author puyv
 * @createTime 2021/11/5 14:08
 * @projectName CoffeeLoverSupportLibrary
 * @className BaseActivity.java
 * @description BaseActivity 核心功能：
 * 1.根据子类所提供的布局文件，进行视图数据绑定
 * 2.为该 UI 层创建对应的 ViewModel 层
 */
public abstract class BaseActivity <VM extends BaseViewModel,VDB extends ViewDataBinding> extends AppCompatActivity implements IView<VM> {

    /**
    * @date 2021/11/5 14:20
    * UI ViewModel 层引用
    */
    private VM mViewModel;

    /**
     * @date 2021/11/5 14:21
     * UI VDB
     */
    private VDB mBinding;

    /**
    * @date 2021/11/6 12:27
    * @params
    * @return
    * @description TODO
    */
    public VM getViewModel(){
        return this.mViewModel;
    }

    public VDB getBinding(){
        return mBinding;
    }

    /**
    * @date 2021/11/5 21:53
    * @params [savedInstanceState]
    * @return void
    * @description 临时补充
    */
    public Context getContext(){
        return this;
    }
    /**
    * ======================================================================================
    */




    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initContentView();
        initViewModel();
        initData(savedInstanceState);

    }

    /**
    *======================================================================================
    */


    /**
    * @date 2021/11/5 14:24
    * @params []
    * @return void
    * @description 对视图进行绑定（DataBinding）
    */
    protected void initContentView(){
        if(isBinding()){
            mBinding = DataBindingUtil.setContentView(this,getLayoutId());
        }else{
            setContentView(getLayoutId());
        }

    }

    /**
     * @date 2021/11/5 14:23
     * @params []
     * @return boolean
     * @description 子类重写该方法，决定是否进行视图绑定，默认将进行视图绑定
     */
    @Override
    public boolean isBinding(){
        return true;
    }


    /**
     ======================================================================================
    */


    /**
    * @date 2021/11/5 15:08
    * @params []
    * @return void
    * @description 初始化 UI 所持有的 ViewModel
    */
    private void initViewModel(){
        mViewModel = createViewModel();
        mViewModel.setModel();
        if(mViewModel != null){
            getLifecycle().addObserver(mViewModel);
            registerUIChangeCallBack();
        }
    }

    /**
    * @date 2021/11/5 15:08
    * @params []
    * @return VM
    * @description IView 接口方法的实现
    */
    @Override
    public VM createViewModel(){
        return obtainViewModel(getVMClass());
    }

    /**
    * @date 2021/11/5 15:10
    * @params []
    * @return java.lang.Class<VM>
    * @description 获取当前对象的 Class 对象
    */
    private Class<VM> getVMClass(){
        Class cls = getClass();
        Class<VM> vmClass = null;
        while (vmClass == null && cls!= null){
            vmClass = getVMClass(cls);
            cls = cls.getSuperclass();
        }
        if(vmClass == null){
            vmClass = (Class<VM>) BaseViewModel.class;
        }
        return vmClass;
    }

    /**
    * @date 2021/11/5 15:11
    * @params [cls]
    * @return java.lang.Class
    * @description 遍历当前 Class 对象的参数，找到 VM
    */
    private Class getVMClass(Class cls){
        Type type = cls.getGenericSuperclass();
        if(type instanceof ParameterizedType){
            Type[] types = ((ParameterizedType)type).getActualTypeArguments();
            for(Type t : types){
                if(t instanceof Class){
                    Class vmClass = (Class)t;
                    if(BaseViewModel.class.isAssignableFrom(vmClass)){
                        return vmClass;
                    }
                }else if(t instanceof ParameterizedType){
                    Type rawType = ((ParameterizedType)t).getRawType();
                    if(rawType instanceof Class){
                        Class vmClass = (Class)rawType;
                        if(BaseViewModel.class.isAssignableFrom(vmClass)){
                            return vmClass;
                        }
                    }
                }
            }
        }
        return null;
    }


    /**
    * @date 2021/11/5 15:15
    * @params [modelClass]
    * @return T
    * @description 通过  ViewModelProvider 获取相应的 ViewModel有则获取，无则创建
    */
    public <T extends ViewModel> T obtainViewModel(@NonNull Class<T> modelClass){
        return new ViewModelProvider(this).get(modelClass);
    }

    /**
    *  ======================================================================================
    */


    /**
     * @date 2021/11/6 14:27
     * @params []
     * @return void
     * @description 数据发生改变时所驱动的 UI 变化,子类实现该方法
     */
    public abstract void registerUIChangeCallBack();

    /**
     *  ======================================================================================
     */



    /**
    * @date 2021/11/5 15:17
    * @params []
    * @return void
    * @description UI 生命周期结束时，先调用父类 super.onDestroy() 被 ViewModel 观察到，ViewModel 先调用 Model 释放资源，在释放 Model
     * 最后 ViewModel 被移除观察者列表 之后 ViewModel 被释放
    */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mViewModel != null){
            getLifecycle().removeObserver(mViewModel);
            mViewModel = null;
        }
        if(mBinding != null){
            mBinding.unbind();
        }
    }




    /**
     * =================================================================================
     */
    /**
     * @date 2021/11/6 15:01
     * @params [clz, bundle]
     * @return void
     * @description 启动 Activity 相关方法
     */
    protected void startActivity(Class<?> clz, Bundle bundle) {
        Intent intent = new Intent(this.getContext(), clz);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
    }

    protected void startActivity(Class<?> clz) {
        startActivity(new Intent(this.getContext(), clz));
    }

    /**
     * @date 2021/11/6 15:02
     * @params
     * @return
     * @description 启动一个新的 Activity 并 Finish 之前的 Activity
     */
    protected void startActivityFinish(Class<?> clz, Bundle bundle){
        Intent intent = new Intent(this.getContext(), clz);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
        this.finish();
    }

    protected void startActivityFinish(Class<?> clz){
        Intent intent = new Intent(this.getContext(), clz);
        startActivity(intent);
        this.finish();
    }
    /**
     * =================================================================================
     */

}
